package generacionCodigo;

import alexico.Simbolo;
import alexico.TablaDeSimbolos;
import codigoIntermedio.Terceto;

public class Assembler {

	private static ArchivoAssembler codigoAss = new ArchivoAssembler("codigoAss.asm");


	public Assembler(){
	}

	private static void generarDeclaracionDeVariables() {
		codigoAss.addLine(".data");
		codigoAss.addLine("\tErrorSuma db \"Error de overflow en suma\", 0");
		codigoAss.addLine("\tErrorProducto db \"Error de overflow en producto\", 0");
		//codigoAss.addLine("\tCadenaEjemplo db \"HELLO WORLD\", 0");
		for (Simbolo s:TablaDeSimbolos.simbolos.values()){
			if (!"String".equals(s.getTipo())){
				codigoAss.addLine(s.toAssembler());
			}
		}
		codigoAss.addLine("\n");		
	}

	private static void cerrarArchivo() {
		codigoAss.cerrarArchivo();		
	}

	private static void cargarFunciones() {
		for (String name_funcion : Terceto.getFunciones().keySet()){
			codigoAss.addLine("\r"+name_funcion+" PROC");			
			Transformer.ambitoFuncion = "_"+name_funcion;
			for (Terceto tfuncion: Terceto.getFunciones().get(name_funcion)){
				String codigoterceto="";
				codigoterceto+=Transformer.transformarTerceto(tfuncion);
				codigoAss.addLine(codigoterceto);
			}
			Transformer.ambitoFuncion="";
			//codigoAss.addLine("\tRET "+TablaDeSimbolos.findValueOfSimbolo(name_funcion));
			codigoAss.addLine("\tMOV _return_de_"+name_funcion+"_main, 0");//+Transformer.regs.getLast_used());
			codigoAss.addLine("\tRET");
			codigoAss.addLine("\t"+name_funcion+" ENDP\n");
		}

	}
	
	private static void cargarFuncionesDeError() {
		codigoAss.addLine("\tOVERFLOWPRODUCTO PROC");
		codigoAss.addLine("\tJO Error_Producto");
		codigoAss.addLine("\tRET");
		codigoAss.addLine("\tOVERFLOWPRODUCTO ENDP");
		codigoAss.addLine("\t");
		codigoAss.addLine("\tOVERFLOWSUMA PROC");
		codigoAss.addLine("\tJO Error_Suma");
		codigoAss.addLine("\tRET");
		codigoAss.addLine("\tOVERFLOWSUMA ENDP");
		codigoAss.addLine("\t");
		codigoAss.addLine("\tError_Producto:");
		codigoAss.addLine("\tprint addr ErrorProducto,10,13");
		codigoAss.addLine("\tinkey");
		codigoAss.addLine("\tinvoke ExitProcess,0");
		codigoAss.addLine("\t");
		codigoAss.addLine("\tError_Suma:");
		codigoAss.addLine("\tprint addr ErrorSuma,10,13");
		codigoAss.addLine("\tinkey");
		codigoAss.addLine("\tinvoke ExitProcess,0");
	}

	public static void generarCodigoAssembler (){
		//Declaracion de variables del assembler
		generarDeclaracionDeVariables ();
		//Declaracion de funciones
		codigoAss.addLine(".code");
		cargarFuncionesDeError ();
		cargarFunciones ();
		//Comenzamos a incluir el main del codigo
		codigoAss.addLine("start:");
		for (Terceto t: Terceto.getTercetos()){
			codigoAss.addLine(Transformer.transformarTerceto(t));
		}
		codigoAss.addLine("\tinkey");
		cerrarArchivo ();
	}
}
